package com.itheima.discuss.service.impl;

import com.itheima.discuss.entity.DiscussEntity;
import com.itheima.discuss.service.DiscussService;
import com.itheima.discuss.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class DiscussServiceImpl implements DiscussService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private MongoTemplate mongoTemplate;

    //todo CRUD
    //添加评论
    @Override
    public void addDiscuss(DiscussEntity discussEntity) {
        //利用工具类 雪花算法 生成ID
        String id = idWorker.nextId() + "";

        discussEntity.setId(id);
        //存入MongoDB
        mongoTemplate.save(discussEntity);
    }

    //查看评论
    @Override
    public List<DiscussEntity> getDiscuss(String articleId) {

        // 构建query
        // Query query = new Query();
        // query.addCriteria(Criteria.where("articleId").is(articleId));

        //select * from tb where articleId = 1
        Query query = new Query(Criteria.where("articleId").is(articleId));

        // db.comment.find({articleId:"1"})

        return mongoTemplate.find(query, DiscussEntity.class);
    }

    //追加回复(更新)
    @Override
    public void addReply(String discussId, DiscussEntity discussEntity) {

        // db.comment.update( {_id:"1"},{$set:{reply:[123]}} )

        Query query = new Query(Criteria.where("_id").is(discussId));

        Update update = new Update();
        update.addToSet("reply", discussEntity);

        mongoTemplate.updateFirst(query, update, DiscussEntity.class);
    }

    //给评论点赞(LikeNums自增)
    @Override
    public void incrLikeNums(String discussId) {

        // db.comment.update({_id:"1"},{$inc:{likeNums:1}})

        Query query = new Query(Criteria.where("_id").is(discussId));

        Update update = new Update();
        update.inc("likeNums", 1);

        mongoTemplate.updateFirst(query, update, DiscussEntity.class);
    }

    //todo 聚合查询
    //按id 统计文章评论量
    @Override
    public Long getTotalCommentNum(String articleId) {

        // db.comment.count({articleId:"2"})

        Query query = new Query(Criteria.where("articleId").is(articleId));

        return mongoTemplate.count(query, DiscussEntity.class);
    }

    //按文章分组，统计每个文章的总点赞数
    @Override
    public List<Map> getArticleLikeNums() {

        //db.comment.aggregate([{$group:{_id:"$articleId",total:{$sum:"$likeNums"}}}])

        //构建Aggregation
        TypedAggregation<DiscussEntity> aggregation = Aggregation.newAggregation(
                DiscussEntity.class,
                Aggregation.group("articleId")  //分组
                        .sum("likeNums")  //求和
                        .as("totalNums")  //别名
        );

        //调用方法,拿到聚合结果,map接收
        AggregationResults<Map> aggregate = mongoTemplate.aggregate(
                aggregation,
                mongoTemplate.getCollectionName(DiscussEntity.class),
                Map.class
        );

        return aggregate.getMappedResults();
    }

    //按文章分组，获取点赞数最多的文章
    @Override
    public Map getMaxLikeNumsArticle() {

//对分组结果数据排序，并按降序排序， 1代表升序，-1代表降序
//对排序后结果，限制结果数量返回
//db.comment.aggregate([{$group:{_id:"$articleId",total:{$sum:"$likeNums"}}},{$sort:{total:-1}},{$limit:1}])

        //构建Aggregation
        TypedAggregation<DiscussEntity> aggregation = Aggregation.newAggregation( DiscussEntity.class,                      Aggregation.group("articleId").sum("likeNums").as("totalNums"),
              Aggregation.sort(Sort.Direction.DESC,"totalNums"),
              Aggregation.limit(1)
        );

        //调用方法,拿到聚合结果,map接收
        AggregationResults<Map> aggregate = mongoTemplate.aggregate(
                aggregation,
                mongoTemplate.getCollectionName(DiscussEntity.class),
                Map.class
        );

        return aggregate.getUniqueMappedResult();
    }
}
